﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace EasyNet.Componets.Core.Algorithms
{
    public sealed class MD5
    {
        private static MD5 _instance;
        /// <summary>
        /// 单一实例
        /// </summary>
        public static MD5 Instance
        {
            get
            {
              
                return _instance = _instance ?? new MD5();
            }
        }

        #region MD5加密
        public string Create(string stringCode, Encoding encoding = null)
        {
            System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create();//实例化一个md5对像
            // 加密后是一个字节类型的数组，这里要注意编码UTF8/Unicode等的选择　
            encoding = encoding ?? Encoding.UTF8;

            byte[] buffer = md5.ComputeHash(encoding.GetBytes(stringCode));

            return Convert(buffer);
        }

        public byte[] CreateBytes(byte[] buffer)
        {
            using (var md5 = new MD5CryptoServiceProvider())
            {
                return md5.ComputeHash(buffer);
            }
        }

        public string Create(byte[] buffer)
        {
            using (var md5 = new MD5CryptoServiceProvider())
            {
                var bytes = md5.ComputeHash(buffer);
                return Convert(bytes);
            }
        }

        public string Create(Stream inputStream)
        {
            using (var md5 = new MD5CryptoServiceProvider())
            {
                var buffer = md5.ComputeHash(inputStream);
                return Convert(buffer);
            }
        }

        private string Convert(byte[] buffer)
        {
            StringBuilder result = new StringBuilder();
            // 通过使用循环，将字节类型的数组转换为字符串，此字符串是常规字符格式化所得
            for (int i = 0; i < buffer.Length; i++)
            {
                // 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母，如果使用大写（X）则格式后的字符是大写字符 
                result.Append(buffer[i].ToString("x2"));
            }
            return result.ToString();
        }
        #endregion

    }
}
